(function(root){

    const RULES = {
        interpolate: /<%=([\s\S]+?)%>/,
        escape: /<%-([\s\S]+?)%>/,
        expression: /<%([\s\S]+?)%>/,
    }

    function template(templateString, settings){
        // var matcher = /<%=([\s\S]+?)%>|<%-([\s\S]+?)%>|<%([\s\S]+?)%>/g
        // 将规则可自定义化，避免↑这样硬编码

        Object.assign(RULES, settings)

        var rule = new RegExp( [
            RULES.interpolate.source,
            RULES.escape.source,
            RULES.expression.source,
        ].join('|'), 'g')

        var source = "_p+='"
        var index = 0

        templateString.replace(rule, function(match, interpolate, escape, expression, offset){

            // 将非js部分内容拼接进去
            source += templateString.slice(index, offset).replace(/\n/g, function(){
                return "\\n"
            })
            index = offset + match.length       // #

            if(interpolate){
                // 插值：
                //      "\n         前行结束，换行
                //      interpolate 本行内容（即插值部分）
                //      \n"         换行，后行开始
                source += "' + \n ((_t=(" + interpolate + ")) == null ? '' : _t) + \n'"
            }
            else if(escape){
                // TODO 字符串逃逸
            }
            else if(expression){
                // 表达式
                //      ;\n         前行结束，换行
                //      expression  本行内容（即表达式部分）
                //      ;\n         本行结束，换行
                //      _p+="       表达式后面继续新一次的文字拼接
                source += "';\n"+ expression + "\n _p+='"
            }
        });
        source += " '; "

        source = "with(obj){\n" + source + "}\n"

        source = "var _t, _p='';\n" + source + " return _p;\n" 

        var render = new Function("obj", source)

        var compiledTemplate = function(data){
            return render.call(null, data)
        }
        return compiledTemplate
    }

    root.template = template
})(this)